1 00:00:00,450 --> 00:00:01,050 All right. 2 00:00:01,080 --> 00:00:05,820 Now that we've completed our loading screen and camera scripts, we now need to focus on creating the 3 00:00:05,820 --> 00:00:07,890 functionality for our GUI. 4 00:00:07,920 --> 00:00:13,530 However, before we can start scripting the GUI itself, we need to set up the server service on the 5 00:00:13,530 --> 00:00:17,460 server to allow players to create custom servers that other players can join. 6 00:00:17,490 --> 00:00:20,970 So in Server script service, we're going to have our own custom service. 7 00:00:21,000 --> 00:00:23,430 In here we're going to call it server service. 8 00:00:23,940 --> 00:00:28,500 And this service is basically going to act as a class for us, where we'll be able to create new server 9 00:00:28,500 --> 00:00:32,940 objects that keep track of who is inside the server, whether the server has a password, and a whole 10 00:00:32,940 --> 00:00:34,170 bunch of other functions. 11 00:00:34,200 --> 00:00:39,210 Now, before we get started, I want to create a standard for communication between the client and the 12 00:00:39,210 --> 00:00:42,420 server, and we can do so by creating our own enumeration. 13 00:00:42,420 --> 00:00:44,340 So unreplicated storage. 14 00:00:44,340 --> 00:00:47,820 There is a section of modules here where I've created a custom enum. 15 00:00:47,820 --> 00:00:50,280 And this is called server action enums. 16 00:00:50,280 --> 00:00:55,110 And this server action enum is going to store the different strings that will represent the different 17 00:00:55,110 --> 00:00:59,970 actions that the client can request the server to do, and the actions the server wants the client to 18 00:00:59,970 --> 00:01:00,600 do. 19 00:01:00,600 --> 00:01:03,060 So what we can do here is we can create a table. 20 00:01:03,060 --> 00:01:04,560 I'm going to call it enum. 21 00:01:05,550 --> 00:01:09,210 And inside of this table we're going to have two different key value pairs. 22 00:01:09,210 --> 00:01:12,660 One is going to be a table for actions to the server. 23 00:01:12,660 --> 00:01:14,460 So we'll call it two server. 24 00:01:14,730 --> 00:01:17,430 And another table is going to be actions for the client. 25 00:01:17,430 --> 00:01:18,960 So we'll call it two client. 26 00:01:19,080 --> 00:01:25,110 Now some of the actions the client will make to the server are going to be things like creating a server. 27 00:01:25,110 --> 00:01:26,460 So we'll call it create server. 28 00:01:26,460 --> 00:01:29,250 And we'll just set it equal to a string of create server. 29 00:01:30,710 --> 00:01:33,710 Another action would be like deleting a server. 30 00:01:37,420 --> 00:01:41,260 Another action would be to get all the servers that currently exist. 31 00:01:41,260 --> 00:01:46,930 So when a player joins one of these servers or one of these lobbies, they can grab all of the servers 32 00:01:46,930 --> 00:01:49,720 that currently exist and then display that in their GUI. 33 00:01:49,750 --> 00:01:52,510 We can make a request to join a server. 34 00:01:55,110 --> 00:01:59,820 We can make a request to submit a password to a server. 35 00:01:59,820 --> 00:02:00,360 So we call it. 36 00:02:00,360 --> 00:02:02,820 We could call it a submit password. 37 00:02:07,350 --> 00:02:13,740 The owner of the server can request to the server to, let's say, remove a player from a server. 38 00:02:14,330 --> 00:02:18,830 And a player that's already inside of the server can also request to leave a server. 39 00:02:20,800 --> 00:02:25,270 The last action that could be requested would be the owner of the server wanting to start the game, 40 00:02:25,270 --> 00:02:27,280 so we could call it Start Server. 41 00:02:30,970 --> 00:02:37,240 Now, some actions that the server could make to the client would be things like telling them to add 42 00:02:37,240 --> 00:02:38,980 a server to the server list. 43 00:02:40,840 --> 00:02:44,320 We could tell the client to remove a server from the server list. 44 00:02:46,530 --> 00:02:55,110 We could tell the client to add a player to a server, so we could call it add player to list or add 45 00:02:55,110 --> 00:02:57,150 to player list. 46 00:03:00,920 --> 00:03:04,010 We could tell the client to remove a player from the player list. 47 00:03:10,230 --> 00:03:14,010 We could tell a player that they were maybe removed from a server. 48 00:03:14,010 --> 00:03:18,420 So if the owner of the server kicks them out, we can give them a message so we can do like removed 49 00:03:18,420 --> 00:03:19,890 from server. 50 00:03:23,930 --> 00:03:27,620 We could tell a player to update the server count for a server. 51 00:03:27,620 --> 00:03:32,060 So when other players are joining a server, we want to update the server count on their end so we could 52 00:03:32,060 --> 00:03:34,460 call it update server count. 53 00:03:39,970 --> 00:03:44,770 And last but not least, we could tell the player that they are going to be teleporting. 54 00:03:44,770 --> 00:03:46,750 So let's say the owner of the server starts the game. 55 00:03:46,750 --> 00:03:52,150 We need to teleport them to the next place and to make it look more seamless, we can tell the client 56 00:03:52,150 --> 00:03:57,820 to fade you know, a guy or a frame on the screen that says teleporting, so we can tell them that they're 57 00:03:57,820 --> 00:03:58,780 about to be teleported. 58 00:03:58,780 --> 00:04:00,640 So we can just call this command teleport. 59 00:04:02,040 --> 00:04:05,910 So these are the different actions that the clients can request to the server. 60 00:04:05,910 --> 00:04:09,480 And these are the different actions that the server can tell the client to do. 61 00:04:09,780 --> 00:04:12,120 And then we can return this enum at the end. 62 00:04:12,120 --> 00:04:16,800 And another interesting thing that we could do is we could actually set a meta table on this enum. 63 00:04:17,010 --> 00:04:21,780 And what I'm going to do is I'm going to create an underscore underscore index meta method in here and 64 00:04:21,780 --> 00:04:23,490 set it equal to a lambda function. 65 00:04:23,880 --> 00:04:31,590 Now as we know, this meta method is only going to get called when we try to index this table with a 66 00:04:31,590 --> 00:04:33,360 key that does not exist. 67 00:04:33,360 --> 00:04:37,440 So let's say we try to index an action in two server that did not exist. 68 00:04:37,440 --> 00:04:39,960 Well this meta method would get called. 69 00:04:39,960 --> 00:04:46,710 And what we could do in here is we could just put out an error saying whatever they tried to index, 70 00:04:46,890 --> 00:04:49,710 uh, is not a valid member instead of returning nil. 71 00:04:49,710 --> 00:04:54,720 Because, you know, when we index a table with a key that does not exist, we're just going to get 72 00:04:54,720 --> 00:04:55,200 nil. 73 00:04:55,200 --> 00:05:02,160 But we could also instead have the script error when the player tries to request a key that does not 74 00:05:02,160 --> 00:05:03,000 exist. 75 00:05:03,960 --> 00:05:06,450 So this function gets passed the table itself. 76 00:05:06,450 --> 00:05:08,910 And the key that the player tried to index with. 77 00:05:08,910 --> 00:05:13,650 And what we could do is we could just raise an error here and put a string like percentage s. 78 00:05:13,650 --> 00:05:17,790 So our directive is not a valid member of percentage s. 79 00:05:17,790 --> 00:05:21,420 And we're going to format this with uh the key of course. 80 00:05:21,420 --> 00:05:23,790 So we're going to convert this key to a string. 81 00:05:24,390 --> 00:05:27,330 And then we're just going to use the scriptname. 82 00:05:27,750 --> 00:05:32,400 So basically if we try to index like two server or two client with something that doesn't exist, it'll 83 00:05:32,400 --> 00:05:36,900 error say this key is not a valid member of server action enums. 84 00:05:37,440 --> 00:05:41,040 So now that we have this complete, we can go ahead and go into our server service. 85 00:05:41,280 --> 00:05:45,570 And the services that we're going to need in here is going to be the player service. 86 00:05:48,180 --> 00:05:51,210 We are going to need replicated storage. 87 00:05:54,700 --> 00:05:57,130 We're going to need the teleport service. 88 00:05:59,960 --> 00:06:06,170 And then I'm also going to use the Http service to give different servers or the servers that are created 89 00:06:06,170 --> 00:06:09,140 by the service, a custom or unique ID. 90 00:06:11,300 --> 00:06:14,060 Now let's go ahead and set up the tables for this service. 91 00:06:14,060 --> 00:06:16,880 We're just going to call this table Server service. 92 00:06:18,330 --> 00:06:22,290 And then we're also going to have a meta table for objects created by this service. 93 00:06:22,290 --> 00:06:24,660 So we can just call it server service MT. 94 00:06:26,760 --> 00:06:33,690 Server service MT we're going to set the underscore underscore index meta method to itself. 95 00:06:34,590 --> 00:06:40,260 And then what we're also going to do is we're going to set the underscore underscore new index meta 96 00:06:40,260 --> 00:06:40,980 method. 97 00:06:42,220 --> 00:06:43,810 Equal to a function. 98 00:06:43,810 --> 00:06:48,340 And what this is going to do is just going to error, and it's going to give out a message that says 99 00:06:48,340 --> 00:06:52,360 unable to add new index to object. 100 00:06:53,400 --> 00:07:01,200 So if any script attempts to try to add a new key value pair to our objects, we're going to error because 101 00:07:01,200 --> 00:07:05,130 we only want to add whatever is created by our constructor. 102 00:07:05,730 --> 00:07:11,580 Now some other variables we're going to need is we're going to need a reference to this server event 103 00:07:11,580 --> 00:07:13,920 or this remote function and replicated storage. 104 00:07:13,920 --> 00:07:20,460 So we can call it server event is equal to replicated storage, dot events, dot remotes, dot server 105 00:07:20,460 --> 00:07:20,880 event. 106 00:07:20,880 --> 00:07:25,470 And this is the remote function we're going to use for the client to communicate with the server. 107 00:07:25,590 --> 00:07:27,120 We're going to have another event. 108 00:07:27,120 --> 00:07:29,400 We're going to call update GUI event. 109 00:07:29,490 --> 00:07:34,560 And we're going to use this event to tell our clients to update their GUI when needed. 110 00:07:39,120 --> 00:07:43,110 And last but not least, we're also going to require our server action enums. 111 00:07:43,110 --> 00:07:45,900 So server action enums. 112 00:07:46,700 --> 00:07:49,340 Then replicated storage in the modules folder. 113 00:07:49,370 --> 00:07:52,520 Get the enum of server action enums. 114 00:07:52,580 --> 00:07:58,040 And because we've created our own custom enums, that means we're able to change these values to represent 115 00:07:58,040 --> 00:08:02,720 whatever we'd like, instead of having to go into each script to change whatever these values are. 116 00:08:02,750 --> 00:08:04,670 We can just do it from this one script. 117 00:08:05,520 --> 00:08:10,410 Now we're going to create another table to act as the cache for all the servers in this game. 118 00:08:10,410 --> 00:08:13,620 So it's just going to store all the current servers. 119 00:08:15,380 --> 00:08:20,120 And I'm also going to create another table and I'm going to call it Server private. 120 00:08:20,120 --> 00:08:25,670 And when the purpose of this table is to store all the passwords for any servers. 121 00:08:25,670 --> 00:08:32,270 So instead of storing the password in the server object itself, we want to store the password in this 122 00:08:32,270 --> 00:08:33,890 private table here. 123 00:08:33,950 --> 00:08:37,610 That way we're not able to see it from the object. 124 00:08:37,610 --> 00:08:42,380 And when the players request to see all the servers in the game, they're not going to be able to see 125 00:08:42,380 --> 00:08:44,060 the passwords for them either. 126 00:08:44,480 --> 00:08:47,180 And then last but not least, we're going to create a constant here. 127 00:08:48,190 --> 00:08:53,950 And this constant is going to represent the ID for the other place in our game where we're going to 128 00:08:53,950 --> 00:08:55,120 teleport the players to. 129 00:08:55,150 --> 00:09:00,010 So I'm just going to call it start place ID, and I'm just going to set it for one for now. 130 00:09:00,010 --> 00:09:05,440 But when we create our next place in the game, we're going to want to copy the ID of that place and 131 00:09:05,440 --> 00:09:06,760 paste it in here. 132 00:09:07,330 --> 00:09:13,480 Now, the first private function I want to make is a function to see if an argument matches a particular 133 00:09:13,480 --> 00:09:16,840 type, so we can call it arg matches type. 134 00:09:16,870 --> 00:09:19,240 It'll take an argument, which is anything. 135 00:09:19,860 --> 00:09:25,500 And we want it to match an expected type, which will be a string, and this function will return back 136 00:09:25,500 --> 00:09:26,310 a boolean. 137 00:09:27,340 --> 00:09:29,770 And this function is actually going to be pretty simple. 138 00:09:29,770 --> 00:09:37,510 So the first thing that we could do is if this type of expected type is not equal to a string. 139 00:09:37,510 --> 00:09:44,080 So basically whoever is using this function did not pass the correct, uh, data type to this parameter. 140 00:09:44,680 --> 00:09:52,330 We're just going to error and just say expected type string for expected type. 141 00:09:52,330 --> 00:09:55,990 But we got something else instead. 142 00:09:56,320 --> 00:09:58,840 And then we could go ahead and format this. 143 00:10:00,580 --> 00:10:05,530 Call the format function on it and pass the type of expected type. 144 00:10:06,090 --> 00:10:12,300 Now, if the type of our argument is not equal to an instance. 145 00:10:12,300 --> 00:10:15,660 So we don't want to check the class, but we want to check the type. 146 00:10:15,660 --> 00:10:22,170 And let's say the type of argument is not equal to the expected type. 147 00:10:22,170 --> 00:10:25,170 Then we're going to return false or aka. 148 00:10:25,170 --> 00:10:28,170 This argument does not match our expected type. 149 00:10:29,010 --> 00:10:32,070 However, let's say the type of this argument is an instance. 150 00:10:32,070 --> 00:10:34,020 So let's say it's an instance. 151 00:10:34,930 --> 00:10:39,190 Then we need to make sure that this argument matches the class that we expect. 152 00:10:39,190 --> 00:10:41,110 So if it doesn't. 153 00:10:41,110 --> 00:10:46,000 So let's say this argument is not of the class expected type. 154 00:10:46,000 --> 00:10:49,810 Whatever that type is, then we're also going to return false. 155 00:10:50,140 --> 00:10:52,450 Otherwise we could just return true. 156 00:10:53,200 --> 00:10:58,870 Now, some other functions we're going to need in here is one to check if a player exists already in 157 00:10:58,870 --> 00:11:01,930 a server, so we can just call it is player in server. 158 00:11:03,250 --> 00:11:09,190 We'll have a function to listen when a player is removed from the game, so we can call it on player 159 00:11:09,190 --> 00:11:10,270 removing. 160 00:11:13,840 --> 00:11:19,000 We're also going to have a function to connect to our server event. 161 00:11:19,000 --> 00:11:23,020 So we can call this on an event invoke. 162 00:11:23,760 --> 00:11:31,050 And this just expects a player, an action from that player and any arguments to go with that action. 163 00:11:31,560 --> 00:11:36,420 And then we can go down to this public function section here and create the constructor for our service. 164 00:11:36,450 --> 00:11:39,030 So this function in our server service. 165 00:11:40,820 --> 00:11:42,920 His first going to need an owner. 166 00:11:42,920 --> 00:11:45,650 So we're going to need an owner for a server, right. 167 00:11:45,650 --> 00:11:47,480 Who's going to be the owner of the server? 168 00:11:47,480 --> 00:11:51,020 We're also going to need the maximum size of the server. 169 00:11:51,020 --> 00:11:52,190 So we can just call it max. 170 00:11:52,190 --> 00:11:55,070 Size is going to be a number. 171 00:11:55,900 --> 00:12:01,480 Will have a parameter of whether or not this thing has a password, so has password. 172 00:12:02,760 --> 00:12:04,050 It'll be a boolean. 173 00:12:04,320 --> 00:12:10,440 And then if it does have a password, then we can just pass that password to be the last argument. 174 00:12:10,440 --> 00:12:12,870 So it could be a potential string here. 175 00:12:13,480 --> 00:12:20,140 Some other functions that I want to have to be a part of this service would be to get a server based 176 00:12:20,140 --> 00:12:21,250 on the owner. 177 00:12:21,250 --> 00:12:25,060 So let's say we pass a player, we want to check to see if that player owns a server. 178 00:12:25,060 --> 00:12:30,850 So in server service we can create a function like a get server from owner. 179 00:12:30,850 --> 00:12:33,400 And this would get passed a player object. 180 00:12:33,400 --> 00:12:37,210 We could just call it an owner and it would just be passed a player. 181 00:12:37,210 --> 00:12:42,700 Or we could get passed a string which could be the name of an owner. 182 00:12:43,500 --> 00:12:49,620 Now down here is going to be all the functions that are going to be attached to our meta table or aka, 183 00:12:49,620 --> 00:12:53,820 these are going to be all the functions that are going to be a part of the server objects themselves 184 00:12:53,820 --> 00:12:55,200 and not the class. 185 00:12:55,500 --> 00:13:01,350 So inside of our server service meta table, what's a function we want to have for our server? 186 00:13:01,350 --> 00:13:04,500 Well, we want to be able to add a player to a server. 187 00:13:05,340 --> 00:13:08,910 We want to be able to remove a player from a server. 188 00:13:12,650 --> 00:13:17,840 We want to be able to, let's say, add a player to a whitelist in a server. 189 00:13:17,840 --> 00:13:23,870 So basically if a server has a password, then when a player submits a password, we can check whether 190 00:13:23,870 --> 00:13:25,400 or not that password was correct. 191 00:13:25,400 --> 00:13:30,590 If the password was correct, then we could add that player to a whitelist, which allows them to join 192 00:13:30,590 --> 00:13:31,220 the server. 193 00:13:31,220 --> 00:13:34,550 So we could call this function here something like. 194 00:13:37,610 --> 00:13:40,790 We call it something like AD player. 195 00:13:41,660 --> 00:13:44,570 To whitelist. 196 00:13:45,730 --> 00:13:50,080 And we could also have a function to remove a player from a white list. 197 00:13:50,080 --> 00:13:54,820 So let's say a player joins a password protected server, but then the owner kicks them. 198 00:13:54,820 --> 00:13:56,950 Then we want to remove them from the white list. 199 00:14:02,950 --> 00:14:08,830 We also want to have the ability to, let's say, lock a server, which prevents any players from joining 200 00:14:08,830 --> 00:14:09,850 it or leaving it. 201 00:14:09,850 --> 00:14:14,140 And this will be very useful for when we have to teleport all of the players in the server. 202 00:14:22,940 --> 00:14:25,730 And we could also have one for unlocking a server as well. 203 00:14:26,060 --> 00:14:30,380 Lastly, we'll need a function for destroying a server. 204 00:14:30,380 --> 00:14:33,410 So server service meta table. 205 00:14:33,410 --> 00:14:36,230 We want to have the ability to destroy a server. 206 00:14:36,590 --> 00:14:39,380 Now for this particular service here. 207 00:14:40,350 --> 00:14:48,360 All we need to do is we need to have a function for initializing this service or aka we just want to 208 00:14:48,360 --> 00:14:52,440 connect our function to the different events. 209 00:14:52,440 --> 00:14:56,280 So we could do function server service init. 210 00:14:56,280 --> 00:15:00,990 So initializing the service what we want to do is we want to reference our server event. 211 00:15:00,990 --> 00:15:05,820 And on server invoke can be equal to our on event invoke function. 212 00:15:06,390 --> 00:15:13,290 And then for players dot player removing we can connect that on player removing function. 213 00:15:13,910 --> 00:15:18,770 And that's all we need to do for this initialized section of this service. 214 00:15:18,770 --> 00:15:23,630 And I don't believe we need to start the service, because all it's going to do is listen to these events. 215 00:15:24,170 --> 00:15:29,750 And then at the very end here, we want to make sure to return our server service table. 216 00:15:31,790 --> 00:15:37,040 Okay, so the first thing I think we could fill out here is the constructor for our server service. 217 00:15:37,040 --> 00:15:40,160 So we want to be able to create new server objects. 218 00:15:40,160 --> 00:15:46,970 Before we do anything in this server service, we need to verify the information that is being passed 219 00:15:46,970 --> 00:15:52,250 to our constructor, because this constructor is going to be called when players request to create a 220 00:15:52,250 --> 00:15:52,850 server. 221 00:15:52,850 --> 00:15:55,610 We have no idea what the client is going to be sending to us. 222 00:15:55,610 --> 00:15:55,910 All right? 223 00:15:55,910 --> 00:16:02,870 An exploiter could be sending us random garbage to our constructor and it will cause errors in our script. 224 00:16:02,870 --> 00:16:07,760 So a good practice would be to verify that the information being sent here is correct. 225 00:16:07,760 --> 00:16:13,340 So the first thing we could do is let's say this argument does not match our type of player. 226 00:16:13,340 --> 00:16:21,110 So for the owner, if this is not a player, then we need an error or otherwise we can just return false 227 00:16:21,110 --> 00:16:27,170 and send a message back to the player or the client and tell them something like expected player. 228 00:16:28,020 --> 00:16:34,170 Her owner, but we got or we could say got put a directive here instead. 229 00:16:34,810 --> 00:16:40,120 And we're going to format this string with the type of the owner that was passed to this constructor. 230 00:16:40,120 --> 00:16:47,110 So basically the idea is we're going to be returning a boolean and a string back to the client through 231 00:16:47,110 --> 00:16:50,680 our server event, and they can display this message on our screen. 232 00:16:50,680 --> 00:16:56,050 So that way it can be easy to show the player what went wrong when creating their server or giving them 233 00:16:56,050 --> 00:16:56,860 any messages. 234 00:16:56,860 --> 00:17:01,420 And it also makes it easy for us to debug anything in case something wrong happens. 235 00:17:02,350 --> 00:17:05,350 The next thing we need to check is this max size. 236 00:17:05,350 --> 00:17:11,140 So if this argument doesn't match the type of number, then we also need to return false. 237 00:17:15,530 --> 00:17:18,650 And we can say expected number. 238 00:17:19,940 --> 00:17:24,140 For max size, but we got percentage s instead. 239 00:17:24,140 --> 00:17:30,470 And again we're going to format this with the type of max size. 240 00:17:30,470 --> 00:17:34,310 And we can just basically copy this paste it here. 241 00:17:34,310 --> 00:17:36,950 But instead we're going to do it for has password. 242 00:17:36,950 --> 00:17:38,960 And this has to be a boolean. 243 00:17:39,570 --> 00:17:42,450 So we expected a boolean. 244 00:17:43,480 --> 00:17:49,420 For has password, but we got whatever they passed instead. 245 00:17:51,270 --> 00:17:54,870 And again, we'll do this one last time for the password itself. 246 00:17:54,870 --> 00:17:58,350 So if has password is true. 247 00:17:58,920 --> 00:18:02,130 And let's say. 248 00:18:03,090 --> 00:18:05,910 Um, this does not match the argument. 249 00:18:05,910 --> 00:18:07,050 So. 250 00:18:07,940 --> 00:18:12,620 We'll pass the password here and it has to be of the type string. 251 00:18:12,650 --> 00:18:16,520 Expected string for our password. 252 00:18:17,360 --> 00:18:22,040 Expected string for our password, but we got whatever was passed instead. 253 00:18:25,160 --> 00:18:27,200 And that looks pretty good there. 254 00:18:27,590 --> 00:18:31,970 And you can kind of see how these if statements all read out like basic English. 255 00:18:31,970 --> 00:18:38,720 So if this if not ARG matches type owner player then we return false. 256 00:18:38,720 --> 00:18:44,930 If not uh max size matches number, then we returns false and so on. 257 00:18:45,110 --> 00:18:49,490 Once we have verified that all of the information passed to our constructor is good, then we could 258 00:18:49,490 --> 00:18:50,960 create a new server object. 259 00:18:50,960 --> 00:18:53,720 So I'm going to override self with a new table. 260 00:18:54,530 --> 00:18:58,880 We can set the key value pair of owner in this table to be equal to the owner. 261 00:18:58,970 --> 00:19:03,740 We could set the has password property equal to has password. 262 00:19:04,230 --> 00:19:08,130 We could set the max size equal to max size. 263 00:19:10,460 --> 00:19:12,380 And then we'll have a table in here. 264 00:19:12,380 --> 00:19:14,600 We'll call it players and server. 265 00:19:14,600 --> 00:19:19,250 And this is going to keep track of all the players that are a part of this particular server object. 266 00:19:19,250 --> 00:19:22,490 And of course the first player is obviously going to be the owner. 267 00:19:22,490 --> 00:19:26,090 And that should be the case when we create a new service, just the owner. 268 00:19:26,510 --> 00:19:31,520 We're also going to be creating a table for the white list that will just store all the players cleared 269 00:19:31,520 --> 00:19:32,120 for entry. 270 00:19:32,120 --> 00:19:36,890 For the server, we'll have a property called locked, which will keep track of whether or not it's 271 00:19:36,890 --> 00:19:37,700 locked. 272 00:19:37,700 --> 00:19:42,410 And then last but not least, we'll have a custom ID for the server using the Http service. 273 00:19:42,410 --> 00:19:45,290 And we're going to generate a new UID. 274 00:19:46,390 --> 00:19:53,440 Now, if self dot has password is true, then what we're going to do is we're going to create a table 275 00:19:53,440 --> 00:19:53,680 in here. 276 00:19:53,680 --> 00:19:55,270 I'm going to call it private. 277 00:19:55,270 --> 00:20:00,340 And inside this uh, private table we're going to have a key value pair of password. 278 00:20:00,340 --> 00:20:05,380 And it's going to be simply equal to the password that was passed to our constructor. 279 00:20:05,710 --> 00:20:10,360 Then once we've created this table, we can store it within the server private table that we created 280 00:20:10,360 --> 00:20:11,080 earlier. 281 00:20:11,080 --> 00:20:15,670 And we're going to use the ID of the server as the key for this table. 282 00:20:15,670 --> 00:20:19,210 And then we could just set it equal to this private table that we just created. 283 00:20:19,210 --> 00:20:24,340 So at any point in the future when we need to check the password for a particular server, we just check 284 00:20:24,340 --> 00:20:30,070 our server private table, pass the ID of that server, and then we can get the private table that stores 285 00:20:30,070 --> 00:20:32,320 the password for this particular table. 286 00:20:32,320 --> 00:20:38,140 Once we have finished doing all of that, then we can insert this table inside of our current servers 287 00:20:38,140 --> 00:20:38,860 table. 288 00:20:39,280 --> 00:20:45,640 And then we can set the meta table of this table to our server service meta table. 289 00:20:45,640 --> 00:20:52,750 And the reason we're doing this last is because we have overridden the new index here to error. 290 00:20:52,750 --> 00:20:57,670 So if we set the amount of table the first thing before we started creating all these key value pairs 291 00:20:57,670 --> 00:20:59,350 here it would error of course. 292 00:20:59,350 --> 00:21:01,090 So we need to do it at the very end. 293 00:21:01,570 --> 00:21:04,360 And then we could just basically just return this. 294 00:21:04,930 --> 00:21:10,330 At the end of our constructor, so we'll just return true that everything went well and then we return 295 00:21:10,330 --> 00:21:11,530 the object. 296 00:21:11,890 --> 00:21:15,640 Now let's go ahead and fill out some of these other basic functions we have in here, like a get server 297 00:21:15,640 --> 00:21:16,480 from owner. 298 00:21:16,510 --> 00:21:18,040 This one should be pretty easy. 299 00:21:18,040 --> 00:21:23,230 All we need to do is we need to loop through every single server object that is inside of our current 300 00:21:23,230 --> 00:21:29,770 servers table, and all we need to do is we need to check if the server dot owner is equal to the owner 301 00:21:29,770 --> 00:21:38,410 passed to this function, or if the server dot owner dot name is equal to the owner passed to this function 302 00:21:38,410 --> 00:21:40,720 because it could be either a player or a string. 303 00:21:42,040 --> 00:21:45,670 If it matches, then we can just return the server and that's it. 304 00:21:46,810 --> 00:21:47,200 All right. 305 00:21:47,200 --> 00:21:51,040 So the next function we can fill out is adding a player to a server. 306 00:21:51,040 --> 00:21:54,970 So we can pass to this function the player we wish to add to the server. 307 00:21:58,470 --> 00:22:02,850 And this function can return back to us a boolean and a string. 308 00:22:05,230 --> 00:22:06,640 Because the plan is here. 309 00:22:06,640 --> 00:22:11,140 Let's say, uh, we request to join a server and we get added. 310 00:22:11,140 --> 00:22:16,600 Then we can get a message sent back to us, like we successfully joined the server, or we could get 311 00:22:16,600 --> 00:22:21,250 sent a message back to us, like, the server is full or the server is locked or something like that. 312 00:22:21,250 --> 00:22:23,680 So let's go ahead and verify that first of all. 313 00:22:23,680 --> 00:22:31,720 So let's say if the server is locked so self dot locked then we're going to return false and tell the 314 00:22:31,720 --> 00:22:34,150 player that the server is locked. 315 00:22:36,210 --> 00:22:39,570 If the number of people in the server. 316 00:22:39,570 --> 00:22:45,510 So we're going to check the length of our players and server table if that's equal to self dot max size, 317 00:22:45,510 --> 00:22:47,400 then we're also going to return false. 318 00:22:47,400 --> 00:22:50,070 And we're going to say that the server is full. 319 00:22:51,520 --> 00:22:58,600 Now let's say that the player is already in a server, but they're an exploiter and they're trying to 320 00:22:58,600 --> 00:23:03,490 mess with our functions and our remote events, and they're trying to join multiple different servers. 321 00:23:03,490 --> 00:23:06,970 So what we need to do is we need to verify that they're not in a server. 322 00:23:06,970 --> 00:23:10,840 So if, uh, is player and server. 323 00:23:10,840 --> 00:23:16,840 So let's say this player we want to add is in the server, then we need to return false and say you 324 00:23:16,840 --> 00:23:18,790 are already in a server. 325 00:23:18,850 --> 00:23:21,070 That means we can go ahead and fill out this function here. 326 00:23:21,070 --> 00:23:22,210 So let's scroll up. 327 00:23:23,600 --> 00:23:27,170 And we'll pass a player to this function. 328 00:23:27,440 --> 00:23:33,110 And what we could do is we could loop through every single server in our current servers table. 329 00:23:34,060 --> 00:23:39,070 And what we could do is we could check if this player is inside of this server. 330 00:23:39,070 --> 00:23:42,550 Dot players in server. 331 00:23:44,730 --> 00:23:51,030 If they are, then we could do something like return the server, and once we're done looping and we 332 00:23:51,030 --> 00:23:53,250 didn't find them, we could just return false. 333 00:23:54,980 --> 00:23:59,420 So that means when this function gets called right here, if this player is on a server, it'll return 334 00:23:59,420 --> 00:24:01,130 the server back to this point. 335 00:24:01,130 --> 00:24:06,530 And since we're checking it in a condition, it'll evaluate to true and it'll return false and tell 336 00:24:06,530 --> 00:24:08,210 them that they're already in a server. 337 00:24:08,960 --> 00:24:12,050 Uh, another thing we need to check is whether or not the server has a password. 338 00:24:12,050 --> 00:24:14,720 So if self dot has password. 339 00:24:16,080 --> 00:24:21,450 And let's say that this player is not within the white list for the server. 340 00:24:21,450 --> 00:24:28,470 So not table dot find and self dot white list player to add. 341 00:24:30,010 --> 00:24:39,190 Then we need to return false and tell them you must submit the correct password to join this server. 342 00:24:39,700 --> 00:24:44,680 Otherwise, once we have verified that all the information is correct, then we can loop through every 343 00:24:44,680 --> 00:24:48,760 single player that is inside of this server. 344 00:24:48,760 --> 00:24:51,310 So self dot players in server. 345 00:24:51,940 --> 00:24:57,040 And what we could do is we could use our update guy event to fire to those players that they need to 346 00:24:57,040 --> 00:25:01,420 add a new player to the server's player list so we could fire client. 347 00:25:02,170 --> 00:25:09,130 To this particular player and using the server actions enums to client, we could tell them to add to 348 00:25:09,130 --> 00:25:10,060 player list. 349 00:25:10,060 --> 00:25:11,410 And who do we want to add? 350 00:25:11,410 --> 00:25:13,960 Well, we want to add this particular player here. 351 00:25:15,150 --> 00:25:21,630 And then once that's done, we can insert this newly added player into our self dot players and server 352 00:25:21,630 --> 00:25:22,380 table. 353 00:25:25,080 --> 00:25:34,590 And then we'll fire to all of the clients in our game that we want them to update the server count for 354 00:25:34,590 --> 00:25:41,670 a particular server so we can do server actions, enums, dot two, client update, server count, and 355 00:25:41,670 --> 00:25:47,190 we want to update the server count for self or this particular server object here. 356 00:25:47,940 --> 00:25:53,250 And then once we've done that we can just return true and say something like joined server. 357 00:25:54,000 --> 00:25:57,300 Okay, so what do we want to do for removing a player from the server? 358 00:25:57,330 --> 00:25:59,340 Well, we can create a parameter. 359 00:25:59,340 --> 00:26:01,230 We can call it player to remove. 360 00:26:01,230 --> 00:26:02,820 And this is going to be a player. 361 00:26:03,790 --> 00:26:08,110 And we can also return a boolean. 362 00:26:09,310 --> 00:26:11,980 And a string from this function. 363 00:26:12,440 --> 00:26:15,740 What we need to do is, of course check whether or not the server is locked. 364 00:26:15,740 --> 00:26:21,860 So if self dot locked then return false and say something like server is locked. 365 00:26:24,730 --> 00:26:28,990 Otherwise, the next thing we need to check is whether or not this player we want to remove is actually 366 00:26:28,990 --> 00:26:29,830 in the server. 367 00:26:29,830 --> 00:26:35,560 So what I'm going to do is I'm going to use the table dot find function to get the index in our players 368 00:26:35,560 --> 00:26:40,450 in server table, we want to find what index this player is. 369 00:26:40,750 --> 00:26:42,730 So we'll create a variable called I. 370 00:26:43,560 --> 00:26:48,960 And let's say there is no index or basically this player doesn't exist in the server, then we can just 371 00:26:48,960 --> 00:26:53,040 return false and say player is not in server. 372 00:26:54,500 --> 00:27:01,460 Otherwise we can remove this player from our self-taught players and server. 373 00:27:03,280 --> 00:27:05,230 And pass that index there. 374 00:27:06,030 --> 00:27:09,990 And actually, another thing that I want to add here is I want to have another parameter. 375 00:27:09,990 --> 00:27:12,510 We're going to call it removed by owner. 376 00:27:12,930 --> 00:27:14,070 It's going to be a boolean. 377 00:27:14,070 --> 00:27:18,450 And basically when this function gets called we want to see if this function was called by a player 378 00:27:18,450 --> 00:27:23,700 who voluntarily was removed from the server, or if they were removed by the owner. 379 00:27:24,510 --> 00:27:29,430 So if they were removed by the owner, if this particular player was removed by the owner, then we 380 00:27:29,430 --> 00:27:34,260 want to give them a message telling them something like, you were kicked from the server so we could 381 00:27:34,260 --> 00:27:40,500 use the update guy event and fire to this particular client player to remove, and we can tell them 382 00:27:40,500 --> 00:27:44,970 that they were removed from the server so we could do server actions. 383 00:27:44,970 --> 00:27:45,660 Enum. 384 00:27:46,810 --> 00:27:50,920 To client and the action is removed from server. 385 00:27:51,840 --> 00:27:57,300 And we can tell them a message like you have been kicked from the server. 386 00:27:59,530 --> 00:28:06,070 Otherwise, we can just give them a message like you left the server so we could basically do the exact 387 00:28:06,070 --> 00:28:12,130 same thing here, but give them a different message, like you left the server. 388 00:28:12,400 --> 00:28:16,750 So we just want to give a different message based on whether or not they were removed by the owner. 389 00:28:17,460 --> 00:28:20,520 The next thing we need to check is if the server has a password. 390 00:28:20,520 --> 00:28:24,300 So if as password then we need to remove them from the white list. 391 00:28:24,300 --> 00:28:32,370 So we can call that remove player from white list function and pass the player. 392 00:28:32,460 --> 00:28:35,010 And we'll fill this function out in a second. 393 00:28:36,260 --> 00:28:44,180 And then we can loop through every single player in ipairs self, dot players and server and tell them 394 00:28:44,180 --> 00:28:51,290 to remove a particular player from the player list so we can use our update guy event fire to this particular 395 00:28:51,290 --> 00:28:52,160 client. 396 00:28:52,400 --> 00:28:54,470 Give them the action. 397 00:28:55,670 --> 00:28:58,640 Of remove from player list. 398 00:28:59,520 --> 00:29:02,100 And who do you want to remove from the player list? 399 00:29:02,130 --> 00:29:03,900 Well, this particular player. 400 00:29:05,110 --> 00:29:10,510 And then once that's done, we can use the update event again and fire to all of the players in our 401 00:29:10,510 --> 00:29:14,770 game that we want them to update the server count for a particular server. 402 00:29:14,770 --> 00:29:19,630 So two client update server count and it's going to be for the server. 403 00:29:20,540 --> 00:29:24,080 Then we can return true and say something like player removed. 404 00:29:25,510 --> 00:29:28,450 So let's go ahead and fill out these two functions here. 405 00:29:28,450 --> 00:29:31,720 Add player to whitelist and remove player from whitelist. 406 00:29:32,460 --> 00:29:35,790 So for this first one, this will just take a player. 407 00:29:38,180 --> 00:29:43,640 And basically all we need to do here is just insert this player into the self dot whitelist table. 408 00:29:43,850 --> 00:29:44,990 And that's it. 409 00:29:44,990 --> 00:29:50,480 And then for remove player from whitelist, all we need to do is get the index where this player resides 410 00:29:50,480 --> 00:29:51,860 within the whitelist. 411 00:29:55,220 --> 00:29:57,560 And we'll get a player pass to this function. 412 00:29:59,290 --> 00:30:03,400 So if they are inside of our whitelist table then we can just remove them. 413 00:30:06,660 --> 00:30:08,550 And that's all we need to do there. 414 00:30:09,570 --> 00:30:13,560 Let's go ahead and actually fill out these two functions as well, because this should be pretty easy. 415 00:30:13,560 --> 00:30:16,620 All we need to do is set self dot lock to true. 416 00:30:16,950 --> 00:30:19,830 And here set self dot lock to false. 417 00:30:19,830 --> 00:30:20,700 And that's it. 418 00:30:21,740 --> 00:30:24,350 Now for destroying a server. 419 00:30:24,440 --> 00:30:27,260 We need to do a few things. 420 00:30:27,260 --> 00:30:32,240 First, we need to loop through every single player that is inside of this server. 421 00:30:32,240 --> 00:30:35,390 So self dot players in server. 422 00:30:36,180 --> 00:30:40,170 Well, we need to do is we need to tell them that they were removed from the server because the server 423 00:30:40,170 --> 00:30:41,400 is going to be deleted. 424 00:30:41,400 --> 00:30:47,040 So we can use the update GUI event and fire to this particular player. 425 00:30:47,040 --> 00:30:52,050 And we can give them the action of remove from server. 426 00:30:52,050 --> 00:30:55,740 And we'll give them a message like the server was deleted. 427 00:30:57,460 --> 00:31:04,210 Then we can update to all of the clients in our game to remove the server from the server list. 428 00:31:05,210 --> 00:31:10,160 So server action enums to client dot remove server. 429 00:31:12,340 --> 00:31:14,590 And the server is going to be self. 430 00:31:15,780 --> 00:31:23,430 And then we can remove the server from our current servers table using table dot find to get the index 431 00:31:23,790 --> 00:31:25,170 where it resides. 432 00:31:27,010 --> 00:31:32,200 The next thing we need to do is to check to see whether or not the server had a key value pair within 433 00:31:32,200 --> 00:31:33,700 our server private table. 434 00:31:33,700 --> 00:31:40,660 So if server private self.id then we can just set this to nil. 435 00:31:42,530 --> 00:31:48,830 And then last but not least, we can use the table dot clear function to clear out all the key value 436 00:31:48,830 --> 00:31:52,070 pairs in this table, or basically free up all the memory. 437 00:31:52,700 --> 00:31:55,760 And that's all we need to do for our destroy function. 438 00:31:56,660 --> 00:32:02,150 So the last couple of things that we need to fill out is our on player removing and our on event invoke 439 00:32:02,150 --> 00:32:03,110 functions. 440 00:32:03,560 --> 00:32:06,680 So let's go ahead and do this one first because it should be pretty easy. 441 00:32:06,710 --> 00:32:10,400 Remember this function gets called when a player is removed from the game. 442 00:32:10,400 --> 00:32:13,100 So we'll get a player passed to this function. 443 00:32:14,130 --> 00:32:20,910 And basically what we want to do is we want to check, um, if this player that is removed from the 444 00:32:20,910 --> 00:32:24,840 game, uh, was the owner of a server. 445 00:32:24,990 --> 00:32:31,890 So we could create a variable called server, and we're going to use the server service and use the 446 00:32:31,890 --> 00:32:35,400 function get server from owner and pass this player. 447 00:32:36,470 --> 00:32:40,220 So if this player was an owner of a server, then we need to destroy it. 448 00:32:40,220 --> 00:32:47,630 So if server then server destroy and that's it. 449 00:32:48,050 --> 00:32:53,030 The next thing we need to check is whether or not this player, uh, was inside of a server. 450 00:32:53,030 --> 00:32:56,480 So they weren't the owner of the server, but they were inside of a server. 451 00:32:56,480 --> 00:33:02,630 Then what we need to do is we need to use our Is player and server function and pass the player. 452 00:33:02,630 --> 00:33:04,160 And we'll get a server back here. 453 00:33:04,160 --> 00:33:07,520 So we'll just override this variable that we just created. 454 00:33:08,430 --> 00:33:10,170 And if server. 455 00:33:11,300 --> 00:33:18,050 Then we can just use the remove player function and pass this particular player. 456 00:33:18,990 --> 00:33:19,500 Okay. 457 00:33:19,500 --> 00:33:22,980 So this is the last function that we're going to go ahead and have to fill out. 458 00:33:22,980 --> 00:33:28,440 And this one is going to be pretty long because we have to listen to all of the different actions that 459 00:33:28,440 --> 00:33:30,570 the client can request the server to do. 460 00:33:31,240 --> 00:33:36,730 So the first actions I want to check here are all of the actions that don't require any arguments to 461 00:33:36,730 --> 00:33:43,450 be passed with them, because I want to be able to check afterwards whether or not this args uh variable 462 00:33:43,450 --> 00:33:49,450 here is equal to a table, and if it isn't, then we just need to return false and say that we expected 463 00:33:49,450 --> 00:33:51,160 a table here for the next actions. 464 00:33:51,160 --> 00:33:52,240 But we didn't get it. 465 00:33:53,290 --> 00:34:03,520 But what we can do here is first we can check the action of like server action enums dot two server 466 00:34:03,520 --> 00:34:04,480 delete server. 467 00:34:04,480 --> 00:34:07,870 So let's say a player wants to delete a server. 468 00:34:07,870 --> 00:34:11,050 Then what we need to do is to check to see if they actually own a server. 469 00:34:11,050 --> 00:34:17,140 So we're going to use the server service and get server from owner with this player. 470 00:34:17,790 --> 00:34:24,240 If they do not own a server, then we need to return false and tell them something like you do not own 471 00:34:24,240 --> 00:34:25,770 any servers. 472 00:34:26,910 --> 00:34:30,060 Otherwise we can just destroy the server. 473 00:34:31,350 --> 00:34:35,610 And then return true and say something like server deleted. 474 00:34:38,020 --> 00:34:44,980 Another action we can check is like server action enums dot two server. 475 00:34:44,980 --> 00:34:48,370 We could do the action of git servers and this one's pretty easy. 476 00:34:48,370 --> 00:34:51,790 All we need to do is return all of the current servers. 477 00:34:51,970 --> 00:34:54,490 And again we don't need any arguments for these. 478 00:34:56,140 --> 00:34:59,200 Else if the action is equal to server action. 479 00:34:59,200 --> 00:35:01,150 Enums dot two server. 480 00:35:02,530 --> 00:35:05,740 And let's say the action is like a player wants to leave a server. 481 00:35:06,700 --> 00:35:10,120 Then what we could do is we could see what server this player is in. 482 00:35:10,120 --> 00:35:17,860 So server to leave is equal to is player and server and pass this player if not. 483 00:35:19,160 --> 00:35:25,130 So let's say this player isn't in a server, then we're just going to return false and tell them you 484 00:35:25,160 --> 00:35:27,140 are not in a server. 485 00:35:27,800 --> 00:35:33,980 Let's say an exploiter owns a server, and for some reason they were messing with our remote function 486 00:35:33,980 --> 00:35:38,510 and tried to leave a server while they were the owner of the server. 487 00:35:38,510 --> 00:35:40,220 Then we need to make a check for that. 488 00:35:40,220 --> 00:35:47,870 So if server to leave owner is equal to this player, then we're going to return false and tell them 489 00:35:47,870 --> 00:35:49,910 you must delete the server. 490 00:35:49,910 --> 00:35:51,920 You can't leave it, you have to delete it. 491 00:35:52,590 --> 00:36:01,710 Otherwise we can go ahead and return the values from the remove player function so we can get this server 492 00:36:01,710 --> 00:36:08,040 to leave and call the remove player function on it and pass this player. 493 00:36:08,730 --> 00:36:16,230 And we're going to pass false for the second argument, because remember that boolean represents whether 494 00:36:16,230 --> 00:36:18,240 or not this player was removed by the owner. 495 00:36:18,240 --> 00:36:22,620 But since a player is requesting to leave the server, then this is going to be false. 496 00:36:23,860 --> 00:36:33,370 Another action is going to be the server action enums to server dot start server. 497 00:36:33,370 --> 00:36:37,330 So let's say the server owner wants to start the game. 498 00:36:38,050 --> 00:36:43,420 Then what we could do is we could get the server that the owner wants to start. 499 00:36:43,420 --> 00:36:49,810 So we're going to use the server service and get server from owner and pass this player. 500 00:36:51,490 --> 00:36:53,770 If they do not own a server or aka. 501 00:36:53,800 --> 00:37:00,010 This didn't return a server back to us, then we're going to return false and tell them you do not own 502 00:37:00,010 --> 00:37:00,940 a server. 503 00:37:04,060 --> 00:37:10,900 Otherwise we're going to lock the server so no player can join it or leave it. 504 00:37:12,480 --> 00:37:14,760 And then we're going to start the server. 505 00:37:15,780 --> 00:37:18,390 So in fact I don't think we actually made this function. 506 00:37:18,390 --> 00:37:22,260 So we want to be able to start the game on a particular server. 507 00:37:22,260 --> 00:37:24,060 So let's go ahead and scroll down here. 508 00:37:25,650 --> 00:37:31,590 And we could just put it like somewhere, like right here and inside of our server service meta table, 509 00:37:31,590 --> 00:37:34,110 we can create a function for starting a game. 510 00:37:35,410 --> 00:37:44,560 And what we could do is we could loop through every single player in ipairs self, dot players and server, 511 00:37:44,950 --> 00:37:47,830 and we want to tell them that they're about to be teleported. 512 00:37:47,980 --> 00:37:52,210 So we could use the update guy event to fire to them. 513 00:37:53,050 --> 00:37:54,370 That. 514 00:37:55,350 --> 00:37:58,530 We want them to be teleported so we could use the server actions. 515 00:37:58,530 --> 00:37:59,340 Enums. 516 00:37:59,610 --> 00:38:01,500 Two client dot teleport. 517 00:38:02,580 --> 00:38:06,180 And then we could just wait a random amount of time, like one second. 518 00:38:06,180 --> 00:38:09,210 So that way they're not teleported instantaneously. 519 00:38:10,110 --> 00:38:17,070 And what I'm going to do is I'm going to use a function in the teleport service called Reserve Server. 520 00:38:17,190 --> 00:38:20,730 So actually let me get the teleport service. 521 00:38:20,730 --> 00:38:24,420 And we're going to call the reserve server function. 522 00:38:24,540 --> 00:38:30,150 And what this does is it returns an access code that can be used to teleport players to a reserved server. 523 00:38:30,850 --> 00:38:36,850 So we need to pass an ID to this that represents the starting place, which will be our start place 524 00:38:36,850 --> 00:38:39,220 ID at the moment it's just equal to one. 525 00:38:39,220 --> 00:38:43,720 But when we create the next place, this is where they're going to be teleported to. 526 00:38:44,400 --> 00:38:49,290 And this will return back to US data for the server, so we can just call it server data. 527 00:38:50,660 --> 00:38:53,990 And then I'm going to create a variable called teleport data. 528 00:38:54,470 --> 00:38:59,630 And this is going to be the data that I'm going to send to the other place. 529 00:38:59,630 --> 00:39:05,420 So that way any server script in the other place can receive any information coming from this place. 530 00:39:05,420 --> 00:39:08,720 So inside of this table I'm just going to create a key value pair. 531 00:39:08,720 --> 00:39:11,300 And I'm going to call it expected players. 532 00:39:11,660 --> 00:39:17,960 And it's going to be equal to the number of players that are inside of self dot players in server. 533 00:39:17,960 --> 00:39:21,830 So we're letting this place know how many players to expect. 534 00:39:22,800 --> 00:39:25,110 And then we can use the teleport service. 535 00:39:25,110 --> 00:39:29,610 And there's a function in there called teleport to private server. 536 00:39:31,540 --> 00:39:32,080 The place. 537 00:39:32,080 --> 00:39:35,470 ID is going to be the start place ID. 538 00:39:36,710 --> 00:39:40,100 The reserved server access code are basically. 539 00:39:40,100 --> 00:39:43,970 The data for the server came from our reserved server function. 540 00:39:43,970 --> 00:39:46,040 So we're going to pass our server data here. 541 00:39:46,810 --> 00:39:53,110 The players we wish to teleport to the server are going to be all of the players in our players in server 542 00:39:53,110 --> 00:39:54,010 table. 543 00:39:54,610 --> 00:40:01,090 This next argument here is spawn name an optional name of the spawn location to spawn at. 544 00:40:01,090 --> 00:40:04,960 So we're just going to pass the generic name of spawn location. 545 00:40:07,280 --> 00:40:13,550 And then lastly, we need to pass any kind of teleport data that we need to pass or aka this table right 546 00:40:13,550 --> 00:40:14,060 here. 547 00:40:14,060 --> 00:40:16,580 So teleport data. 548 00:40:17,140 --> 00:40:19,030 And that's all we need to do there. 549 00:40:19,620 --> 00:40:25,080 So now this function is going to teleport all of our players to this, uh, server that we reserved 550 00:40:25,080 --> 00:40:26,550 using this function right here. 551 00:40:27,000 --> 00:40:30,480 And because we've done that, then we can go ahead and just destroy the server. 552 00:40:31,450 --> 00:40:37,780 Okay, so back in our Onevent invoke function, we have fulfilled all of the different actions we needed 553 00:40:37,780 --> 00:40:44,260 for ones that didn't require any arguments, but now all of the other or remaining actions need to have 554 00:40:44,260 --> 00:40:45,730 arguments supplied to them. 555 00:40:45,730 --> 00:40:50,800 So we need to verify whatever information is being passed from the client is correct. 556 00:40:50,800 --> 00:40:54,880 So we need to make sure that this args parameter here is actually a table. 557 00:40:55,270 --> 00:41:03,250 So if this args is not a table so arg matches type args table. 558 00:41:03,250 --> 00:41:11,890 If it isn't a table, then we need to return false and give them a message like expected type. 559 00:41:12,620 --> 00:41:17,600 Table for args, but we got whatever instead. 560 00:41:18,340 --> 00:41:21,790 And we can format this string with the type of args. 561 00:41:22,630 --> 00:41:27,430 This will stop any junk that is being passed to this function from exploiters. 562 00:41:28,640 --> 00:41:32,390 And then we can go ahead and start listening to all the different actions that require arguments to 563 00:41:32,390 --> 00:41:33,410 be passed to them. 564 00:41:33,410 --> 00:41:39,830 So let's say the action is equal to server action enums dot two server dot create server. 565 00:41:39,830 --> 00:41:41,750 So let's say player wants to create a server. 566 00:41:42,080 --> 00:41:47,390 Well the first thing that we need to verify is if this player is in a server. 567 00:41:47,390 --> 00:41:54,230 So if this player for some reason is in a server and they're somehow firing this event, then we need 568 00:41:54,230 --> 00:42:00,020 to return false and tell them you cannot create a server while in a server. 569 00:42:02,230 --> 00:42:06,460 The next thing we need to do is check whether or not the server is going to have a password. 570 00:42:06,460 --> 00:42:10,810 So instead of args we want to have a key value pair of has password. 571 00:42:11,260 --> 00:42:16,360 So if this table is going to have a password then we need to make sure whatever password they pass to 572 00:42:16,360 --> 00:42:17,620 us is actually a string. 573 00:42:17,620 --> 00:42:18,190 Right. 574 00:42:18,190 --> 00:42:28,000 So if not arg matches type args dot password string, then we're going to return false and say something 575 00:42:28,000 --> 00:42:32,950 like expected type string for password. 576 00:42:32,950 --> 00:42:35,470 But we got whatever instead. 577 00:42:36,560 --> 00:42:41,210 And we're going to format this with the type of args dot password. 578 00:42:42,160 --> 00:42:45,460 Um, we also want to have some specific criteria for a password. 579 00:42:45,460 --> 00:42:50,710 So we don't want it to be less than four characters, but we don't want it to be greater than 12 characters. 580 00:42:50,710 --> 00:42:52,750 And of course, you can change that if you'd like. 581 00:42:52,750 --> 00:42:54,520 But if the number. 582 00:42:55,440 --> 00:43:05,460 Or the length of our password is less than four, or the length of our password is greater than 12, 583 00:43:05,460 --> 00:43:13,680 then we need to return false and tell them something like password must be 4 to 12 characters long. 584 00:43:15,140 --> 00:43:16,700 And that's all we need to do there. 585 00:43:17,550 --> 00:43:23,070 Otherwise, the next thing that we could do is we could use our constructor to get the success and result 586 00:43:23,070 --> 00:43:23,490 from it. 587 00:43:23,490 --> 00:43:27,750 So server service dot new. 588 00:43:27,840 --> 00:43:32,370 We're going to pass the player that requested to create the server because they're going to be the owner. 589 00:43:32,370 --> 00:43:40,200 We're going to pass args dot max size args dot has password and args dot password. 590 00:43:40,200 --> 00:43:43,200 And we're going to convert this password to uppercase. 591 00:43:43,200 --> 00:43:45,840 That way it's consistent across the board. 592 00:43:46,320 --> 00:43:50,460 And all of these different key value pairs are going to be the things that we're going to be passing 593 00:43:50,490 --> 00:43:53,250 to this args table from the client. 594 00:43:53,860 --> 00:43:57,160 So let's say we were not successful in creating a server. 595 00:43:57,160 --> 00:44:01,420 Then what we need to do is we need to return success and the result message. 596 00:44:01,420 --> 00:44:09,400 So like let's say the player for some reason somehow passed, you know, an incorrect type for max size. 597 00:44:09,400 --> 00:44:12,190 Let's say an exploiter was messing with this function. 598 00:44:12,190 --> 00:44:15,190 And we're just going to tell them, hey, you can't do that. 599 00:44:16,050 --> 00:44:16,560 Otherwise. 600 00:44:16,560 --> 00:44:23,310 If we were successful, then what we could do is we could loop through every single, um, player in 601 00:44:23,310 --> 00:44:26,940 our game that's not the owner of the server. 602 00:44:26,940 --> 00:44:33,120 So every single other player and I pairs players get players. 603 00:44:35,710 --> 00:44:42,040 Um, if this player or if this other player is equal to the player that wanted to create the server, 604 00:44:42,040 --> 00:44:45,880 then we're just going to continue looping and you'll see why in a moment. 605 00:44:45,880 --> 00:44:52,420 Because what we're going to do is we're going to use the Updateui event and fire to this client to add 606 00:44:52,420 --> 00:44:53,560 a server. 607 00:44:54,710 --> 00:45:01,130 To the server list, it wouldn't make sense for the owner to add the server to the server list. 608 00:45:01,130 --> 00:45:03,920 When they're the owner of it, they're not going to be able to see it, so there's no point. 609 00:45:04,160 --> 00:45:07,190 So we're just going to fire to all the other players in the game. 610 00:45:08,970 --> 00:45:11,040 We want them to add a server to the server list. 611 00:45:11,040 --> 00:45:16,950 So we could use server action enums to client, and we could tell them to add a server. 612 00:45:16,950 --> 00:45:22,770 And that server is going to be the result from our constructor, which is going to be our server object. 613 00:45:24,230 --> 00:45:31,100 And once we finally done all of that, then we can just return true and tell this player that we successfully 614 00:45:31,100 --> 00:45:34,880 created the server so we can just tell them server created. 615 00:45:36,630 --> 00:45:39,510 And that's it for this particular action. 616 00:45:39,540 --> 00:45:46,110 Now the next action we need to listen to is let's say they want to join a server. 617 00:45:46,110 --> 00:45:47,730 So let's say a player wants to join a server. 618 00:45:48,360 --> 00:45:51,030 So we can do two server. 619 00:45:51,390 --> 00:45:52,530 Join server. 620 00:45:53,720 --> 00:46:00,260 Then what we're going to do is we're going to basically just see if the server that this player wants 621 00:46:00,260 --> 00:46:01,580 to join even exists. 622 00:46:01,730 --> 00:46:05,060 Server to join is equal to server service. 623 00:46:05,060 --> 00:46:11,540 And we're going to use the get server from owner function because the player is going to pass to us 624 00:46:11,540 --> 00:46:13,400 the owner of the server that they want to join. 625 00:46:13,400 --> 00:46:15,080 So we could do args dot owner. 626 00:46:15,870 --> 00:46:18,990 If the server that they want to join does not exist. 627 00:46:19,980 --> 00:46:24,120 Now we're going to return false and say server does not exist. 628 00:46:26,650 --> 00:46:35,080 Otherwise, we're going to get the result from, uh, server to join AD player. 629 00:46:35,680 --> 00:46:42,970 We're going to add this player to the server, and then we're just basically going to return success 630 00:46:43,420 --> 00:46:44,740 results. 631 00:46:44,740 --> 00:46:49,480 And then I also want to return the server itself as well. 632 00:46:49,480 --> 00:46:53,320 And you may be wondering, well, why do you want to return the server object here. 633 00:46:53,380 --> 00:47:01,030 Well, I want to do that because um, if the player does successfully join the server, then they want 634 00:47:01,030 --> 00:47:05,770 to be able to loop through every single player that's already inside of the server and create, uh, 635 00:47:05,770 --> 00:47:10,960 different player frames on their end to show all the different players that are in the server with them. 636 00:47:11,440 --> 00:47:12,010 All right. 637 00:47:12,010 --> 00:47:18,490 The next action that we can fill out is to, let's say, submit a password to the server. 638 00:47:18,490 --> 00:47:22,930 So we could do server action enums dot two server submit password. 639 00:47:22,930 --> 00:47:25,510 So let's say a server is password protected. 640 00:47:25,510 --> 00:47:28,240 Then they need to submit a password for the server. 641 00:47:28,890 --> 00:47:34,860 And again, this, uh, action needs to be supplied the server that this player is trying to submit 642 00:47:34,860 --> 00:47:35,580 the password to. 643 00:47:35,580 --> 00:47:39,870 So we can just call this server to join equal the server service. 644 00:47:40,890 --> 00:47:42,030 Get server from owner. 645 00:47:42,030 --> 00:47:45,930 And again we're going to do args dot owner. 646 00:47:48,030 --> 00:47:55,260 If the server for some reason does not exist, then we're going to return false and say server does 647 00:47:55,260 --> 00:47:56,730 not exist. 648 00:47:59,930 --> 00:48:05,450 Otherwise, the next thing we could check to see is whether or not the server even actually has a password. 649 00:48:05,540 --> 00:48:08,330 So if server to join. 650 00:48:09,900 --> 00:48:11,910 That has password. 651 00:48:11,910 --> 00:48:13,590 So let's say it doesn't have a password. 652 00:48:13,590 --> 00:48:17,880 So if not has password then return false. 653 00:48:17,880 --> 00:48:21,960 And we'll say something like server does not have a password. 654 00:48:23,210 --> 00:48:28,160 Um, otherwise, the next thing we need to check is whether or not the password the player is supplying 655 00:48:28,190 --> 00:48:30,380 to this action is the correct password. 656 00:48:30,410 --> 00:48:36,140 So what we're going to do is we're going to use the string dot upper function to convert their password 657 00:48:36,140 --> 00:48:36,980 to uppercase. 658 00:48:36,980 --> 00:48:42,410 So that way again it stays consistent because when we create the password on the server we've made it 659 00:48:42,410 --> 00:48:43,370 uppercase. 660 00:48:44,330 --> 00:48:50,480 So, um, what we could do inside of ARGs, we can create a key value pair like submitted password. 661 00:48:50,480 --> 00:48:52,700 This will be the password that the player submits. 662 00:48:53,480 --> 00:48:59,300 And if this password does not match the password that is inside of our server private table. 663 00:48:59,300 --> 00:49:04,820 And again we need to pass the server to join.id and then get the password. 664 00:49:05,990 --> 00:49:12,470 So if the password does not match, then we're going to return false and say password was incorrect. 665 00:49:14,350 --> 00:49:14,860 Otherwise. 666 00:49:14,860 --> 00:49:19,990 Once we have finally verified all this information, then we can do server. 667 00:49:19,990 --> 00:49:24,430 To join, we need to add this player to the white list for the server. 668 00:49:25,040 --> 00:49:30,410 And then we're just going to return true and tell them that they were successful in submitting the correct 669 00:49:30,410 --> 00:49:31,250 password. 670 00:49:32,610 --> 00:49:34,050 All right, we're almost done here. 671 00:49:34,050 --> 00:49:35,730 Just hold on to your horses. 672 00:49:36,400 --> 00:49:38,350 If the action. 673 00:49:40,130 --> 00:49:45,350 Is equal to server action enums dot two server dot remove player. 674 00:49:45,350 --> 00:49:47,480 So let's say the owner wants to remove a player. 675 00:49:47,780 --> 00:49:52,070 Then again we need to check the server that this player owns. 676 00:49:52,070 --> 00:49:57,170 So server service get server from owner player. 677 00:49:57,890 --> 00:50:02,000 If the player requesting this action for some reason doesn't own a server. 678 00:50:02,000 --> 00:50:11,870 So if not a owner server, then we can return false and tell them you do not own any servers. 679 00:50:14,430 --> 00:50:20,880 Otherwise we can get the player they wish to remove using the player service. 680 00:50:21,980 --> 00:50:32,360 So players, and we're going to find the first child that matches the args dot player to remove. 681 00:50:32,360 --> 00:50:35,060 So again we're going to create another key value pair. 682 00:50:35,060 --> 00:50:35,570 In here. 683 00:50:35,570 --> 00:50:39,260 We'll just store the string or the name of the player. 684 00:50:39,260 --> 00:50:41,900 And we'll see if they exist within our player service. 685 00:50:43,420 --> 00:50:50,440 If this player does not exist in our game, then we're going to return false and say player does not 686 00:50:50,440 --> 00:50:52,750 exist in the game. 687 00:50:54,020 --> 00:51:02,360 Otherwise we're going to use the owner server, um, and use the remove player function inside of it 688 00:51:02,360 --> 00:51:04,820 and pass this player that we wish to remove. 689 00:51:05,210 --> 00:51:06,260 And we're going to pass. 690 00:51:06,260 --> 00:51:07,010 True. 691 00:51:07,130 --> 00:51:12,410 Because again, we need to pass a boolean of whether or not this player is being removed voluntarily 692 00:51:12,410 --> 00:51:14,330 or by the owner. 693 00:51:14,570 --> 00:51:20,090 And then this function returns back to us, uh, a boolean and a string. 694 00:51:20,090 --> 00:51:24,680 So we can just return that here at the end of this section of our if statement. 695 00:51:25,640 --> 00:51:29,360 And I'm pretty sure that's actually all the actions we needed to fulfill. 696 00:51:29,600 --> 00:51:34,940 Let's go ahead and verify that we have fulfilled all of those different ones. 697 00:51:35,720 --> 00:51:36,560 Looks like we have. 698 00:51:36,560 --> 00:51:42,230 So we have one, two, three, four, five, six, seven. 699 00:51:43,170 --> 00:51:46,410 Eight different actions and we can count the number of actions here. 700 00:51:46,410 --> 00:51:49,020 So there's four, five, six, seven, eight. 701 00:51:49,020 --> 00:51:49,560 Cool. 702 00:51:49,560 --> 00:51:54,540 We have successfully filled out all of the different actions that can be requested to the server. 703 00:51:55,980 --> 00:52:02,280 If somehow we've reached it to the very end of this function, and the player's action did not match 704 00:52:02,280 --> 00:52:09,360 any of the actions in here, then we're just going to return false and tell them requested action did 705 00:52:09,360 --> 00:52:12,960 not match any possible actions. 706 00:52:13,820 --> 00:52:16,340 And I think that's it. 707 00:52:16,340 --> 00:52:17,570 I'm pretty sure. 708 00:52:17,570 --> 00:52:19,100 Let's go ahead and verify. 709 00:52:19,880 --> 00:52:23,330 We have everything that we needed filled out. 710 00:52:24,070 --> 00:52:25,240 And it looks like we have. 711 00:52:25,240 --> 00:52:25,840 Perfect. 712 00:52:25,840 --> 00:52:30,490 So the next thing we need to do is we need to go ahead and fill out the local script that's going to 713 00:52:30,490 --> 00:52:37,210 handle the GUI on the client, and that guy is going to handle all the different frames for the server 714 00:52:37,210 --> 00:52:40,690 browser, or being the owner of the server and things like that. 715 00:52:40,690 --> 00:52:45,760 And that script is also going to handle to fire, you know, different actions to the server for like 716 00:52:45,760 --> 00:52:49,570 removing players from a server or joining a server and things like that. 717 00:52:49,870 --> 00:52:52,060 So thanks for sticking through this longer lecture. 718 00:52:52,060 --> 00:52:54,910 I know it was a little while, but I'll go ahead and see you in the next one.